package com.wkg.lotterysystem.common.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * =============================================================
 * 项目名称：lotterysystem
 * 模块名称：公共配置模块
 * 类 名 称：DirectRabbitConfig
 * 功能描述：RabbitMQ 直连模式（Direct）配置，包含队列、交换机及其绑定
 * =============================================================
 */
@Configuration
public class DirectRabbitConfig {

    /**
     * 队列名称：DirectQueue
     * 说明：用于接收直连交换机中路由键匹配的消息
     */
    public static final String QUEUE_NAME = "DirectQueue";

    /**
     * 交换机名称：DirectExchange
     * 说明：直连类型交换机，按照路由键匹配转发消息
     */
    public static final String EXCHANGE_NAME = "DirectExchange";

    /**
     * 路由键：DirectRouting
     * 说明：消息发送时必须指定该路由键，才会被路由到 DirectQueue
     */
    public static final String ROUTING = "DirectRouting";


    /**
     * 死信队列
     */
    public static final String DLX_QUEUE_NAME = "DlxDirectQueue";


    public static final String DLX_EXCHANGE_NAME = "DlxDirectExchange";


    public static final String DLX_ROUTING = "DlxDirectRouting";

    /**
     * 声明队列：DirectQueue
     */
    @Bean
    public Queue directQueue() {
        // durable:是否持久化,默认是false,持久化队列：会被存储在磁盘上，当消息代理重启时仍然存在，暂存队列：当前连接有效
        // exclusive:默认也是false，只能被当前创建的连接使⽤，⽽且当连接关闭后队列即被删除。此参考优先级⾼于durable
        // autoDelete:是否⾃动删除，当没有⽣产者或者消费者使⽤此队列，该队列会⾃动删除。
        // return new Queue("DirectQueue",true,true,false);

        // ⼀般设置⼀下队列的持久化就好,其余两个就是默认false
        // return new Queue(QUEUE_NAME, true);

        // 正常队列绑定死信交换机
        return QueueBuilder.durable(QUEUE_NAME)
                .deadLetterExchange(DLX_EXCHANGE_NAME)
                .deadLetterRoutingKey(DLX_ROUTING).build();
    }

    /**
     * 声明直连交换机：DirectExchange
     *
     * <ul>
     *   <li>durable = true：交换机持久化</li>
     *   <li>autoDelete = false：无队列绑定时不自动删除</li>
     * </ul>
     *
     * @return 持久化的 DirectExchange 对象
     */
    @Bean
    public DirectExchange directExchange() {
        return new DirectExchange(EXCHANGE_NAME, true, false);
    }

    /**
     * 队列与交换机绑定（Binding）
     *
     * <p>基于 Direct 模式，只有当消息的路由键与 ROUTING 完全匹配时，才会投递到该队列。</p>
     *
     * @return Binding 对象，表示 DirectQueue 与 DirectExchange 的绑定关系
     */
    @Bean
    public Binding bindingDirect() {
        return BindingBuilder.bind(directQueue())
                .to(directExchange())
                .with(ROUTING);
    }


    /**
     * 死信队列
     *
     * @return 持久化队列 Queue 对象
     */
    @Bean
    public Queue dlxQueue() {
        return new Queue(DLX_QUEUE_NAME, true);
    }

    /**
     * 死信交换机
     *
     * @return 持久化的 DirectExchange 对象
     */
    @Bean
    public DirectExchange dlxExchange() {
        return new DirectExchange(DLX_EXCHANGE_NAME, true, false);
    }

    /**
     * 死信队列与交换机绑定
     */
    @Bean
    public Binding dlxDirect() {
        return BindingBuilder.bind(dlxQueue())
                .to(dlxExchange())
                .with(DLX_ROUTING);
    }


    /**
     * 配置消息转换器：Jackson2JsonMessageConverter
     *
     * <p>将消息对象序列化为 JSON，便于不同语言或平台之间传输。</p>
     *
     * @return MessageConverter 对象，用于消息序列化/反序列化
     */
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}
